Element UI 二次封装实现下拉树组件

您所在的位置:网站首页 自定义组件 v-model Element UI 二次封装实现下拉树组件

Element UI 二次封装实现下拉树组件

2023-04-10 06:11| 来源: 网络整理| 查看: 265

使用element ui 二次封装实现下拉树组件,可以搜索,可以动态绑定

一 实现效果图 1.1 单选模式 单选模式.gif 1.2 多选模式 多选模式.gif 二 相关说明 2.1 框架以及版本 1、element-ui 2.15.1 2 2、vue 2.6.11 2.2 组件概述

封装的下拉树,结合了element ui中的下拉组件 el-select 与 树结构组件 el-tree,取两个组件中的一些属性,在此基础上进行的封装。其中可通过v-model对数据进行动态绑定。自行封装扩展性不高,可能会有一些问题,需求不同,可自行进行封装。

2.3 组件api 相关属性 属性 说明 类型 默认值 defaultValue/v-model 值 String, Number, Array - treeData 树结构数据源 Array [] treeProps 替换treeNode 中 label, children 字段为 treeData 中对应的字段 Object {label: ‘name’, children: ‘children’} nodeKey 树结构数据key取值,数据唯一,默认id String id clearable 是否显示清空功能 Boolean false multiple 是否多选 Boolean false placeholder 选择框默认文字 String 请选择 showSearch 是否显示搜索框 Boolean false searchPlaceholder 搜索框默认文字 String 请输入关键字 collapseTags 多选时是否将选中值按文字的形式展示 Boolean true

2 相关方法

名称 说明 参数 change 数据发生变化 数据,选中的节点 removeTag 多选模式下,点击删除单个tag触发 当前选中的值 clear 清空选项触发 - 三 代码实现 3.1 组件页面代码 3.2 组件JS部分代码 const defaultProps = { children: 'children', // 子级字段 label: 'name' // 展示字段 } export default { name: 'CustomTreeSelect', model: { prop: "defaultValue", event: "change" }, props: { // v-model值 defaultValue: { type: [String, Number, Array] }, // 数据源 treeData: { type: Array, default () { return [] } }, // 替换 treeNode 中 label, children 字段为 treeData 中对应的字段 treeProps: { type: Object, default () { return defaultProps } }, // 树结构key的取值,数据唯一, 默认为id nodeKey: { type: String, default: 'id' }, // 是否显示清空功能 clearable: { type: Boolean, default: false }, // 是否多选 multiple: { type: Boolean, default: false }, // 选择框默认文字 placeholder: { type: String, default: '请选择' }, // 搜索框默认文字 searchPlaceholder: { type: String, default: '请输入关键字' }, // 是否显示搜索框 showSearch: { type: Boolean, default: false }, // 多选时是否将选中值按文字的形式展示 collapseTags: { type: Boolean, default: true } }, data() { return { // 下拉框选中值 selectValue: '', // 下拉框选中回显值 selectLabel: '', // 下拉框Option的值,设置为undefined,防止选中 selectOptionValue: undefined, // 树数据搜索内容 treeFilterText: '', // 默认展开 defaultExpandedKeys: [] } }, computed: { // 树结构是否显示复选框(多选情况下出现) showCheckbox () { return this.multiple }, // select 下拉框自定义的类名-可自行修改 popperClass () { let classNames = ['custom-tree-select-popper'] if (this.showSearch) { classNames.push('custom-tree-select-search') } return classNames.join(' ') }, // 下拉框实例 treeSelectRef () { return this.$refs.treeSelectRef }, // 树结构实例 optionTreeRef () { return this.$refs.optionTreeRef } }, watch: { // 监听默认值,对数据赋值 defaultValue: { deep: true, immediate: true, handler (newValue, oldValue) { const { multiple } = this if (newValue) { if (!this.reloadTreeCheck) this.handleSetTreeCheck(newValue); } else { this.selectValue = multiple ? [] : '' this.selectLabel = multiple ? [] : '' } } }, treeFilterText (value) { setTimeout(() => { this.handleInputChange(value) }, 300) } }, mounted () { // 重新加载树结构选中 false-加载 true-不加载 this.reloadTreeCheck = false }, methods: { /** 多选模式下,点击移除单个tag */ handleSelectRemoveTag (tag) { this.reloadTreeCheck = false const { selectValue } = this if (isArray(selectValue)) { this.selectValue.shift() } this.$emit('removeTag', tag) }, /** select框的清除按钮 */ handleSelectClear () { this.reloadTreeCheck = false const { multiple } = this const value = multiple ? [] : '' this.treeFilterText = '' this.selectValue = [ ...value ] this.selectLabel = [ ...value ] this.$emit('change', value, null) this.$emit('clear') }, /** 树节点 点击时 */ handleNodeClick (node) { const { treeProps, multiple, nodeKey } = this if (multiple) return if (node.children && node.children.length > 0) return this.selectValue = node[nodeKey] this.selectLabel = node[treeProps.label] this.$emit('change', this.selectValue, node) // 下拉框失去焦点,隐藏下拉面板 this.treeSelectRef.blur() // this.treeFilterText = '' }, /** 树节点 复选框选中时 */ handleTreeCheck (node, values) { const { treeProps } = this const { checkedKeys, checkedNodes } = values this.selectValue = checkedKeys const lableValues = checkedNodes.map(nodeItem => { return nodeItem[treeProps.label] }) this.selectLabel = lableValues this.$emit('change', checkedKeys, checkedNodes) }, /** 设置回显数据 */ handleSetTreeNode (value) { const { optionTreeRef, treeProps } = this this.selectValue = value if (isArray(value)) { // 多选 this.selectLabel = value.map(item => { const treeNode = optionTreeRef.getNode(item) return treeNode.data[treeProps.label] }) } else { // 单选 const treeNode = optionTreeRef.getNode(value) this.selectLabel = treeNode.data[treeProps.label] } }, /** 处理数据树结构展开,并处理选中效果 */ handleTreeExpandKeys (value) { const { optionTreeRef, multiple } = this if (isArray(value) && multiple) { optionTreeRef.setCheckedKeys(value) value.forEach(item => { const treeNode = optionTreeRef.getNode(item) if (treeNode && treeNode.parent) { this.setTreeExpandKeys(treeNode.parent) } }) } else { optionTreeRef.setCurrentKey(value) const treeNode = optionTreeRef.getNode(value) if (treeNode && treeNode.parent) { this.setTreeExpandKeys(treeNode.parent) } } }, /** 处理树结构父级展开 */ setTreeExpandKeys (node) { node.expanded = true if (node.parent) { this.setTreeExpandKeys(node.parent) } }, /** 搜索树节点 */ filterTreeNode (value, data, node) { if (!value) { // if (node.expanded) node.expanded = false return true } const { treeProps: { label } } = this return data[label].indexOf(value) !== -1; }, /** 设置树结构回显选中 */ handleSetTreeCheck (value) { if (!this.reloadTreeCheck && value) { this.$nextTick(() => { this.handleSetTreeNode(value) this.handleTreeExpandKeys(value) this.reloadTreeCheck = true }) } }, /** 搜索框中按下回车失去焦点触发 */ handleInputChange (value) { this.optionTreeRef.filter(value) } } } /** * 判断数据类型是否为数组 */ function isArray(arg) { if (typeof Array.isArray === 'undefined') { return Object.prototype.toString.call(arg) === '[object Array]' } return Array.isArray(arg) } 3.3 组件样式代码

这里有覆盖修改到element-ui的原始样式, 注:如果需要修改下拉框的高度,修改样式代码中.el-select-dropdown__wrap 中的高度属性

.custom-tree-select-search { .el-select-dropdown__list { padding: 0; } } .custom-tree-select-popper { .el-scrollbar { .el-select-dropdown__wrap { max-height: 365px !important; } .el-scrollbar__bar.is-vertical { z-index: 3; } } } .tree-select-search { position: sticky; top: 0; z-index: 2; display: block; padding: 6px; background: #fff; } .tree-select-option-item { background: #fff; overflow: scroll; height: 200px; overflow-x: hidden; } .el-scrollbar .el-scrollbar__view .el-select-dropdown__item{ height: auto; min-height: 200px; padding: 0; overflow: hidden; } 四 如何使用 4.1 组件引入注册后页面 4.2 参数设置 export default { data () { return { treeData: [ { id: "321C8FF6CC6046D79CD8877526054BCF", text: "1100 北京市本级", name: "1100 北京市本级", code: "1100" }, { id: "157EAB9EA1A34D0F824E97C2C7D9F0CA", text: "1101 市辖区", name: "1101 市辖区", code: "1101", children: [ { id: "B08F7DB39F124ACFB2171508D8C5C0FD", text: "110101 东城区", name: "110101 东城区", code: "110101" }, { id: "2AF3A9766AAD433A95D4EADE5FB97839", text: "110102 西城区", name: "110102 西城区", code: "110102" }, { id: "A2058EAE12674B3D9BA3710C87DDB111", text: "110105 朝阳区", name: "110105 朝阳区", code: "110105" }, { id: "C6BC2FE9FE86493291EE59171133ABB5", text: "110106 丰台区", name: "110106 丰台区", code: "110106" }, { id: "06E478CB634F4FC19EC0381D55751218", text: "110107 石景山区", name: "110107 石景山区", code: "110107" }, { id: "DD0B1A29473D4053989938700B73AE26", text: "110108 海淀区", name: "110108 海淀区", code: "110108" }, { id: "5D3FF6E7729E43F9B813EAAB80796E41", text: "110109 门头沟区", name: "110109 门头沟区", code: "110109" }, { id: "349609893FAC47BC97509B8FC411059A", text: "110111 房山区", name: "110111 房山区", code: "110111" }, { id: "1E5B2DC4A1E84C959BB78D6E1B49A1DF", text: "110112 通州区", name: "110112 通州区", code: "110112" }, { id: "2C9DC40AEFF8454ABF8A2EE6AD0A2DB5", text: "110113 顺义区", name: "110113 顺义区", code: "110113" }, { id: "5C0342E4E41841AD837E365DB79E81B7", text: "110114 昌平区", name: "110114 昌平区", code: "110114" }, { id: "DF25016580634FD39307FC0E18E7CF4F", text: "110115 大兴区", name: "110115 大兴区", code: "110115" }, { id: "8DC99ABF109D40ED899552A08FE07C63", text: "110116 怀柔区", name: "110116 怀柔区", code: "110116" }, { id: "9D2DA21BD26C40CC90B8BB26E1B437AC", text: "110117 平谷区", name: "110117 平谷区", code: "110117" }, { id: "AD5172DDD7D547F5A06F022D64EB4DF5", text: "110118 密云区", name: "110118 密云区", code: "110118" }, { id: "78B4DA4936A44314AD801B15988707D4", text: "110119 延庆区", name: "110119 延庆区", code: "110119" } ] }, { id: "E8ADAB8AFDB24F77B3FA89ED7E9A9F15", text: "1102 县", name: "1102 县", code: "1102" } ], treeProps: { label: 'name', children: 'children' }, treeValue: [], } } } 参考文章

https://element.eleme.cn/#/zh-CN https://blog.csdn.net/R_xxxxx/article/details/106112583 https://blog.csdn.net/sleepwalker_1992/article/details/87894588 https://www.jianshu.com/p/47e13795cfe7 https://blog.csdn.net/Mrchai521/article/details/114993368 https://blog.csdn.net/qq_41791303/article/details/103710456



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3